package org.game.manager;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.collections4.MapUtils;
import org.bean.ActivityEntryInfo;
import org.bean.ActivityInfo;
import org.cache.ActivityInfoCache;
import org.constant.ActionEnum;
import org.constant.ActivityConstant;
import org.constant.smallkey.ActivitySmallKey;
import org.game.cache.OnlinePlayerCache;
import org.game.db.bean.Player;
import org.game.db.bean.PlayerActivity;
import org.game.db.cache.PlayerActivityCache;
import org.game.db.vo.ServerActivityProxy;
import org.game.module.activitybo.ActivityBO;
import org.game.module.event.handler.ActivityFinishEventHandler.ActivityEntryVector;
import org.game.msgBuilder.ActivityMsgBuilder;
import org.game.plugin.event.GameEventPlugin;
import org.game.protobuf.s2c.S2CActivityMsg.ActivityInfoMsg;
import org.game.protobuf.s2c.S2CActivityMsg.PushActivitys;
import org.game.protobuf.s2c.S2CShareMsg.ChangeType;
import org.game.util.ProtoUnit;

import com.google.common.collect.Maps;
import com.sojoys.artifact.factory.message.IMessage;
import com.sojoys.artifact.manager.MessageManager;

/**
 * @author : DengYing
 * @CreateDate : 2018年3月6日 下午5:51:27
 * @Description ：活动管理器
 */
public class ActivityManager {
	private ActivityManager() {
	}

	private static ActivityManager ME = new ActivityManager();

	public static ActivityManager me() {
		return ME;
	}

	/**
	 * 通知活动更新
	 * 
	 * @param player
	 * @param playerActivity
	 */
	public void notifyActivity(Player player, PushActivitys.Builder pushBuilder) {
		IMessage msg = MessageManager.me().create(ActivityBO.getAllActivity, ProtoUnit.toByte(pushBuilder.build()));
		player.getPlayerProxy().sendMsg(msg);
	}

	/**
	 * 接收到活动信息
	 * 
	 * @param list
	 */
	public void receiveActivity(List<ActivityInfo> list) {
		
		// 先加入缓存
		for (ActivityInfo activityInfo : list) {
			// 更新缓存
//			if (activityInfo.getAction() == ActionEnum.REMOVE) {
//				ActivityInfoCache.remove(activityInfo.getId());
//			} else {
				ActivityInfoCache.put(activityInfo.getId(), activityInfo);
//			}
		}
		// 需要推送更新的活动
		List<ActivityInfoMsg.Builder> playerPushs = new ArrayList<>(list.size());
		
		ActivityInfoMsg.Builder activitybuilder = null;
		
		PushActivitys.Builder pushBuilder = null;
		
		Collection<Player> players = OnlinePlayerCache.getAll();
		for (Player player : players) {
			for (ActivityInfo activityInfo : list) {
				if (activityInfo.getAction() != ActionEnum.REMOVE) {
					ActivityInfoCache.put(activityInfo.getId(), activityInfo);
				}
				// 加载不进行客户端通知
				if (activityInfo.getAction() == ActionEnum.DEFAULT) {
					continue;
				}

				// 变更处理
				switch (activityInfo.getDataType()) {
				case ActivityConstant.ACTIVITY_DATA_TYPE_PLAYER:
					activitybuilder = receivePlayerActivity(player, activityInfo);
					break;
				case ActivityConstant.ACTIVITY_DATA_TYPE_SERVER:
					activitybuilder = receiveServerActivity(player,activityInfo);
					break;
				}

				if (activitybuilder != null) {
					playerPushs.add(activitybuilder);
				}
			}
			
			pushBuilder = PushActivitys.newBuilder();
			for (ActivityInfoMsg.Builder builder : playerPushs) {
				pushBuilder.addActivitys(builder);
			}
			
			// 推送
			notifyActivity(player, pushBuilder);
			
			// 重置集合
			playerPushs.clear();
		}
		
		// 删除缓存
		for (ActivityInfo activityInfo : list) {
			// 更新缓存
			if (activityInfo.getAction() == ActionEnum.REMOVE) {
				ActivityInfoCache.remove(activityInfo.getId());
			}
		}
	}

	public ActivityInfoMsg.Builder receiveServerActivity(Player player,ActivityInfo activityInfo) {
		switch (activityInfo.getAction()) {
		case ADD:{
			return ActivityMsgBuilder.createActivityInfoMsg(player,ChangeType.ADD, new ServerActivityProxy(activityInfo));
		}
		case REMOVE:{
			return ActivityMsgBuilder.createActivityInfoMsg(player,ChangeType.DELETE, new ServerActivityProxy(activityInfo));
		}
		case UPDATE:
		case RESET:{
			return ActivityMsgBuilder.createActivityInfoMsg(player,ChangeType.UPDATE, new ServerActivityProxy(activityInfo));
		}
		}
		return null;
	}

	public ActivityInfoMsg.Builder receivePlayerActivity(Player player,ActivityInfo activityInfo) {

		switch (activityInfo.getAction()) {
		case ADD:{
			PlayerActivity playerActivity = ActivityManager.me().acceptActivity(player, activityInfo);
			return ActivityMsgBuilder.createActivityInfoMsg(player,ChangeType.ADD, playerActivity);
		}
		case REMOVE:{
			PlayerActivity playerActivity = PlayerActivityCache.me().getByActivityIdPlayerId(activityInfo.getId(), player.getId());
			if (playerActivity!=null) {
				playerActivity.delete();
				return ActivityMsgBuilder.createActivityInfoMsg(player,ChangeType.DELETE, playerActivity);
			}
			break;
		}
		case UPDATE:{
			PlayerActivity playerActivity = PlayerActivityCache.me().getByActivityIdPlayerId(activityInfo.getId(), player.getId());
			if (playerActivity!=null) {
				return ActivityMsgBuilder.createActivityInfoMsg(player,ChangeType.UPDATE, playerActivity);
			}
			break;
		}
		case RESET:{
			PlayerActivity playerActivity = PlayerActivityCache.me().getByActivityIdPlayerId(activityInfo.getId(), player.getId());
			if (playerActivity!=null) {
				playerActivity.getEntry().clear();
				playerActivity.update();
				return ActivityMsgBuilder.createActivityInfoMsg(player,ChangeType.UPDATE, playerActivity);
			}
			break;
		}
		}
		return null;
	}
	
	/** 检查活动修改 */
	public void checkActivityChange(Player player){
		
		List<PlayerActivity> playerActivitys = player.getPlayerActivitysFkPlayerId();

		// 检测活动删除
		for (PlayerActivity playerActivity : playerActivitys) {
			ActivityInfo activityInfo = ActivityInfoCache.getById(playerActivity.getActivityId());
			if (activityInfo == null) {
				playerActivity.delete();
			}else {
				// 检查版本号
				if (activityInfo.getVer()!=playerActivity.getVer()) {
					playerActivity.delete();
				}
			}
		}
		
		// 检测活动新增
		Collection<ActivityInfo> runingActivitys = ActivityInfoCache.getAllCache();
		for (ActivityInfo activityInfo : runingActivitys) {
			if (activityInfo.getDataType() == ActivityConstant.ACTIVITY_DATA_TYPE_PLAYER) {
				PlayerActivity playerActivity = PlayerActivityCache.me().getByActivityIdPlayerId(activityInfo.getId(), player.getId());
				if (playerActivity == null) {
					acceptActivity(player, activityInfo);
				}
			}
		}
	}

	/**
	 * 接取活动
	 * @param player
	 * @param activityInfo
	 */
	public PlayerActivity acceptActivity(Player player, ActivityInfo activityInfo) {
		PlayerActivity playerActivity = PlayerActivityCache.me().getByActivityIdPlayerId(activityInfo.getId(), player.getId());
		if (playerActivity != null) {
			playerActivity.delete();
		}
		playerActivity = new PlayerActivity(0, activityInfo.getId(),activityInfo.getVer(), player.getId(), Maps.newHashMap(), Maps.newHashMap());
		playerActivity.insert();
		
		Map<Integer, ActivityEntryInfo> entrys = activityInfo.getEntrys();
		
		for (Entry<Integer, ActivityEntryInfo> e : entrys.entrySet()) {
			int entryId = e.getKey();
			ActivityEntryInfo entry = e.getValue();
			Map params = entry.getFinishParams();
			
			Map<Integer, Integer> entryInfo =  (Map<Integer, Integer>) playerActivity.getEntry().computeIfAbsent(entryId, k -> new HashMap<Integer, Integer>(2));
			int status = MapUtils.getIntValue(entryInfo, ActivitySmallKey.STATUS);
			int progress = MapUtils.getIntValue(entryInfo, ActivitySmallKey.PROGRESS);
			// 检查待完成的条目
			if (status == ActivityConstant.ENTRY_STATUS_RUNING) {
				GameEventPlugin.eventConditionInit(player, new ActivityEntryVector(playerActivity, entryInfo), entry.getFinishCondId(), params,progress,entry.getProgress());						
			}
		}
		return playerActivity;
	}
}
